package service

import (
	"context"
	"crypto/rand"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"github.com/google/uuid"
	"go.uber.org/zap"
	"go-file-perception-model/internal/config"
	"go-file-perception-model/internal/logger"
	"go-file-perception-model/internal/model"
	"go-file-perception-model/internal/repository"
	"go-file-perception-model/pkg/vector"
)

// IndexManager 索引管理器
type IndexManager struct {
	fileRepo        repository.FileRepository
	vectorDB        vector.VectorDB
	fileProcessor   *FileProcessor
	fileCollector   *FileCollector
	directoryMgr    *DirectoryManager
	fileMonitorRepo repository.FileMonitorRepository
	indexingTasks   map[string]*IndexingTask
	taskMutex       sync.RWMutex
	config          *config.FileIndexConfig
}

// IndexingTask 索引任务
type IndexingTask struct {
	ID             string
	Directories    []string
	Recursive      bool
	Force          bool
	Status         string // "pending", "running", "completed", "failed"
	Progress       int
	TotalFiles     int
	ProcessedFiles int // 已处理的文件数
	StartTime      time.Time
	EndTime        *time.Time
	Error          error
}

// NewIndexManager 创建索引管理器实例
func NewIndexManager(fileRepo repository.FileRepository, fileProcessor *FileProcessor, fileCollector *FileCollector, directoryMgr *DirectoryManager, fileMonitorRepo repository.FileMonitorRepository, cfg *config.FileIndexConfig) *IndexManager {
	return &IndexManager{
		fileRepo:        fileRepo,
		vectorDB:        fileRepo.GetVectorDB(),
		fileProcessor:   fileProcessor,
		fileCollector:   fileCollector,
		directoryMgr:    directoryMgr,
		fileMonitorRepo: fileMonitorRepo,
		indexingTasks:   make(map[string]*IndexingTask),
		config:          cfg,
	}
}

// StartIndexing 开始索引任务
func (m *IndexManager) StartIndexing(req model.IndexRequest) (string, error) {
	// 创建任务ID
	taskID := uuid.New().String()

	// 创建索引任务
	task := &IndexingTask{
		ID:          taskID,
		Directories: req.Directories,
		Recursive:   req.Recursive,
		Force:       req.Force,
		Status:      "pending",
		StartTime:   time.Now(),
	}

	// 添加到任务列表
	m.taskMutex.Lock()
	m.indexingTasks[taskID] = task
	m.taskMutex.Unlock()

	// 异步执行索引任务
	go m.executeIndexingTask(task)

	return taskID, nil
}

// executeIndexingTask 执行索引任务
func (m *IndexManager) executeIndexingTask(task *IndexingTask) {
	// 更新任务状态为运行中
	m.updateTaskStatus(task.ID, "running", 0, 0)

	// 为每个目录注册并设置活动目录
	for _, dir := range task.Directories {
		// 注册目录
		_, err := m.directoryMgr.RegisterDirectory(dir)
		if err != nil {
			m.updateTaskStatus(task.ID, "failed", 0, 0)
			task.Error = fmt.Errorf("failed to register directory %s: %w", dir, err)
			logger.Error("Failed to register directory", zap.String("directory", dir), zap.Error(task.Error))
			return
		}

		// 设置活动目录
		if err := m.directoryMgr.SetActiveDirectory(dir); err != nil {
			m.updateTaskStatus(task.ID, "failed", 0, 0)
			task.Error = fmt.Errorf("failed to set active directory %s: %w", dir, err)
			logger.Error("Failed to set active directory", zap.String("directory", dir), zap.Error(task.Error))
			return
		}

		// 如果强制重新索引，先删除现有索引
		if task.Force {
			// 删除该目录下的所有文件索引（仅在vectorDB可用时）
			if m.vectorDB != nil {
				filter := &vector.Filter{
					Must: []vector.Condition{
						{
							Key:   "file_path",
							Match: &vector.MatchValue{Value: dir},
						},
					},
				}
				if err := m.vectorDB.DeletePointsByFilter(context.Background(), filter); err != nil {
					m.updateTaskStatus(task.ID, "failed", 0, 0)
					task.Error = fmt.Errorf("failed to delete existing indices: %w", err)
					logger.Error("Failed to delete existing indices", zap.Error(task.Error))
					return
				}
			}
		}

		// 收集当前目录的文件
		files, err := m.fileCollector.CollectFiles(dir, task.Recursive)
		if err != nil {
			m.updateTaskStatus(task.ID, "failed", 0, 0)
			task.Error = fmt.Errorf("failed to collect files from directory %s: %w", dir, err)
			logger.Error("Failed to collect files", zap.String("directory", dir), zap.Error(task.Error))
			return
		}

		// 更新任务总文件数
		task.TotalFiles += len(files)

		// 处理当前目录的文件
		processedFiles := 0
		for _, filePath := range files {
			// 检查任务是否被取消
			if task.Status == "cancelled" {
				return
			}

			// 处理文件
			if err := m.processFile(filePath); err != nil {
				logger.Error("Failed to process file", zap.String("file", filePath), zap.Error(err))
				// 继续处理下一个文件
				continue
			}

			processedFiles++
			// 更新任务进度
			progress := int(float64(processedFiles) / float64(task.TotalFiles) * 100)
			m.updateTaskStatus(task.ID, "running", progress, processedFiles)
		}

		// 更新目录统计信息
		if err := m.directoryMgr.UpdateDirectoryStats(dir, len(files), processedFiles); err != nil {
			logger.Error("Failed to update directory stats", zap.String("directory", dir), zap.Error(err))
		}

		// 更新目录最后索引时间
		if err := m.directoryMgr.UpdateDirectoryLastIndexedTime(dir); err != nil {
			logger.Error("Failed to update directory last indexed time", zap.String("directory", dir), zap.Error(err))
		}
	}

	// 更新任务状态为已完成
	m.updateTaskStatus(task.ID, "completed", 100, task.TotalFiles)
	now := time.Now()
	task.EndTime = &now
}

// ProcessFile 处理单个文件
func (m *IndexManager) ProcessFile(filePath string) error {
	// 确定文件所属的目录并设置活动目录
	if err := m.ensureActiveDirectoryForFile(filePath); err != nil {
		return fmt.Errorf("failed to set active directory for file: %w", err)
	}

	// 使用文件处理器处理文件
	fileChunks, err := m.fileProcessor.ProcessFile(filePath)
	if err != nil {
		return fmt.Errorf("failed to process file: %w", err)
	}

	// 保存到向量数据库（仅在vectorDB可用时）
	if m.vectorDB != nil {
		// 获取当前集合名称
		collectionName := m.vectorDB.GetCollection()
		logger.Info("Inserting file chunks to vector database", 
			zap.String("file", filePath), 
			zap.Int("chunks", len(fileChunks)),
			zap.String("collection", collectionName))
		
		if err := m.vectorDB.InsertPoints(context.Background(), fileChunks); err != nil {
			return fmt.Errorf("failed to insert chunks to vector database: %w", err)
		}
		
		logger.Info("File chunks successfully inserted to vector database", 
			zap.String("file", filePath), 
			zap.Int("chunks", len(fileChunks)),
			zap.String("collection", collectionName))
	}

	logger.Info("File processed successfully", zap.String("file", filePath), zap.Int("chunks", len(fileChunks)))
	return nil
}

// ensureActiveDirectoryForFile 确保为文件设置正确的活动目录
func (m *IndexManager) ensureActiveDirectoryForFile(filePath string) error {
	// 获取所有目录
	directories, err := m.directoryMgr.ListAllDirectories()
	if err != nil {
		return fmt.Errorf("failed to list directories: %w", err)
	}

	// 标准化文件路径
	normalizedFilePath := filepath.Clean(filePath)
	
	// 找到包含此文件的目录
	var targetDir *model.DirectoryMonitorRecord
	for _, dir := range directories {
		// 标准化目录路径
		normalizedDirPath := filepath.Clean(dir.DirectoryPath)
		
		// 检查文件是否在此目录下
		if isFileInDirectory(normalizedFilePath, normalizedDirPath) {
			if targetDir == nil || len(normalizedDirPath) > len(filepath.Clean(targetDir.DirectoryPath)) {
				// 选择最具体的（路径最长的）目录
				targetDir = dir
			}
		}
	}

	if targetDir == nil {
		// 尝试自动注册目录
		logger.Warn("No registered directory found for file, attempting to register parent directory", 
			zap.String("file", filePath))
		
		// 尝试从配置的索引目录中找到匹配的目录
		
		// 检查父目录是否在配置的索引目录中
		for _, configDir := range m.config.IndexDirectories {
			normalizedConfigDir := filepath.Clean(configDir)
			if isFileInDirectory(normalizedFilePath, normalizedConfigDir) {
				// 注册目录
				dirRecord, err := m.directoryMgr.RegisterDirectory(normalizedConfigDir)
				if err != nil {
					logger.Error("Failed to auto-register directory", 
						zap.String("directory", normalizedConfigDir), 
						zap.Error(err))
					continue
				}
				targetDir = dirRecord
				logger.Info("Auto-registered directory for file", 
					zap.String("file", filePath),
					zap.String("directory", normalizedConfigDir))
				break
			}
		}
		
		if targetDir == nil {
			return fmt.Errorf("no registered directory found for file: %s (checked directories: %v)", 
				filePath, m.config.IndexDirectories)
		}
	}

	// 设置活动目录
	if err := m.directoryMgr.SetActiveDirectory(targetDir.DirectoryPath); err != nil {
		return fmt.Errorf("failed to set active directory: %w", err)
	}

	logger.Info("Set active directory for file processing", 
		zap.String("file", filePath),
		zap.String("directory", targetDir.DirectoryPath),
		zap.String("collection", targetDir.CollectionName))

	return nil
}

// isFileInDirectory 检查文件是否在指定目录下
func isFileInDirectory(filePath, dirPath string) bool {
	// 标准化路径分隔符
	filePath = filepath.ToSlash(filePath)
	dirPath = filepath.ToSlash(dirPath)
	
	// 确保目录路径以分隔符结尾
	if !strings.HasSuffix(dirPath, "/") {
		dirPath += "/"
	}
	
	// 检查文件路径是否以目录路径开头
	return strings.HasPrefix(filePath+"/", dirPath) || strings.HasPrefix(filePath, dirPath)
}

// processFile 处理单个文件（内部方法）
func (m *IndexManager) processFile(filePath string) error {
	// 获取文件信息
	fileInfo, err := os.Stat(filePath)
	if err != nil {
		return fmt.Errorf("failed to get file info: %w", err)
	}

	// 获取文件修改时间
	modTime := fileInfo.ModTime()

	// 获取当前活动目录
	activeDir, err := m.directoryMgr.GetActiveDirectory()
	if err != nil {
		return fmt.Errorf("failed to get active directory: %w", err)
	}

	// 设置向量数据库的活动集合
	if m.vectorDB != nil {
		m.vectorDB.SetCollection(activeDir.CollectionName)
		logger.Info("Set active collection for vector database", 
			zap.String("collection", activeDir.CollectionName),
			zap.String("directory", activeDir.DirectoryPath))
	}

	// 检查文件是否已存在于数据库中
	fileRecord, err := m.fileMonitorRepo.GetFileRecordByPath(activeDir.ID, filePath)
	if err == nil && fileRecord != nil {
		// 文件已存在，检查是否需要重新索引
		if fileRecord.IndexedAt.After(modTime) {
			// 文件未被修改，跳过处理
			logger.Debug("File unchanged, skipping indexing", zap.String("file", filePath))
			return nil
		}
	}

	// 计算文件内容的SHA256哈希值
	fileContent, err := ioutil.ReadFile(filePath)
	if err != nil {
		return fmt.Errorf("failed to read file content: %w", err)
	}

	hash := sha256.Sum256(fileContent)
	hashStr := hex.EncodeToString(hash[:])

	// 如果文件已存在，检查哈希值是否相同
	if err == nil && fileRecord != nil && fileRecord.FileHash == hashStr {
		// 文件内容未改变，跳过处理
		logger.Debug("File content unchanged, skipping indexing", zap.String("file", filePath))
		return nil
	}

	// 处理文件
	fileChunks, err := m.fileProcessor.ProcessFile(filePath)
	if err != nil {
		return fmt.Errorf("failed to process file: %w", err)
	}

	// 保存到向量数据库（仅在vectorDB可用时）
	if m.vectorDB != nil {
		// 获取当前集合名称
		collectionName := m.vectorDB.GetCollection()
		logger.Info("Inserting file chunks to vector database", 
			zap.String("file", filePath), 
			zap.Int("chunks", len(fileChunks)),
			zap.String("collection", collectionName))
		
		if err := m.vectorDB.InsertPoints(context.Background(), fileChunks); err != nil {
			return fmt.Errorf("failed to insert chunks to vector database: %w", err)
		}
		
		logger.Info("File chunks successfully inserted to vector database", 
			zap.String("file", filePath), 
			zap.Int("chunks", len(fileChunks)),
			zap.String("collection", collectionName))
	}

	// 更新文件监控记录
	if err == nil && fileRecord != nil {
		// 更新现有记录
		fileRecord.FileSize = fileInfo.Size()
		fileRecord.FileModTime = modTime
		fileRecord.FileHash = hashStr
		fileRecord.IsIndexed = true
		fileRecord.IndexedAt = time.Now()
		if err := m.fileMonitorRepo.UpdateFileRecord(fileRecord); err != nil {
			logger.Error("Failed to update file record", zap.String("file", filePath), zap.Error(err))
		}
	} else {
		// 创建新记录
		fileName := filepath.Base(filePath)
		newFileRecord := &model.FileMonitorRecord{
			ID:         generateUUID(),
			DirectoryID: activeDir.ID,
			FilePath:    filePath,
			FileName:    fileName,
			FileSize:    fileInfo.Size(),
			FileModTime: modTime,
			FileHash:    hashStr,
			IsIndexed:   true,
			IndexedAt:   time.Now(),
			CreatedAt:   time.Now(),
			UpdatedAt:   time.Now(),
		}
		if err := m.fileMonitorRepo.CreateFileRecord(newFileRecord); err != nil {
			logger.Error("Failed to create file record", zap.String("file", filePath), zap.Error(err))
		}
	}

	logger.Info("File processed successfully", zap.String("file", filePath), zap.Int("chunks", len(fileChunks)))
	return nil
}

// generateUUID 生成UUID
func generateUUID() string {
	b := make([]byte, 16)
	_, err := rand.Read(b)
	if err != nil {
		// 如果随机数生成失败，使用时间戳作为备选方案
		return fmt.Sprintf("%d", time.Now().UnixNano())
	}
	return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:16])
}

// updateTaskStatus 更新任务状态
func (m *IndexManager) updateTaskStatus(taskID, status string, progress, processedFiles int) {
	m.taskMutex.Lock()
	defer m.taskMutex.Unlock()

	if task, exists := m.indexingTasks[taskID]; exists {
		task.Status = status
		task.Progress = progress
		task.ProcessedFiles = processedFiles
		if processedFiles > 0 && processedFiles > task.TotalFiles {
			task.TotalFiles = processedFiles
		}
	}
}

// GetIndexStatus 获取索引状态
func (m *IndexManager) GetIndexStatus() (*model.IndexStatus, error) {
	logger.Info("Getting index status")
	
	// 获取所有目录
	directories, err := m.directoryMgr.ListAllDirectories()
	if err != nil {
		return nil, fmt.Errorf("failed to list directories: %w", err)
	}
	
	// 如果没有目录，返回默认状态
	if len(directories) == 0 {
		logger.Info("No directories found, returning default status")
		return &model.IndexStatus{
			TotalFiles:      0,
			IndexedFiles:    0,
			TotalChunks:     0,
			IndexedChunks:   0,
			LastIndexedTime: time.Now(),
			IsIndexing:      false,
		}, nil
	}
	
	// 计算所有集合中的总点数和文件统计
	var totalPoints uint64 = 0
	var totalFiles int = 0
	var indexedFiles int = 0
	var lastIndexedTime time.Time
	
	logger.Info("Calculating statistics for directories", zap.Int("directory_count", len(directories)))
	
	// 遍历所有目录
	for _, dir := range directories {
		logger.Info("Processing directory statistics", 
			zap.String("directory", dir.DirectoryPath),
			zap.String("collection", dir.CollectionName))
		
		// 从数据库获取实际的文件统计信息
		fileRecords, err := m.fileMonitorRepo.GetFileRecordsByDirectoryID(dir.ID)
		if err != nil {
			logger.Error("Failed to get file records for directory", 
				zap.String("directory", dir.DirectoryPath), 
				zap.Error(err))
			continue
		}
		
		// 统计文件数量
		dirTotalFiles := len(fileRecords)
		dirIndexedFiles := 0
		for _, record := range fileRecords {
			if record.IsIndexed {
				dirIndexedFiles++
			}
			// 更新最后索引时间
			if record.IndexedAt.After(lastIndexedTime) {
				lastIndexedTime = record.IndexedAt
			}
		}
		
		totalFiles += dirTotalFiles
		indexedFiles += dirIndexedFiles
		
		logger.Info("Directory file statistics", 
			zap.String("directory", dir.DirectoryPath),
			zap.Int("total_files", dirTotalFiles),
			zap.Int("indexed_files", dirIndexedFiles))
		
		// 检查vectorDB是否可用并计算点数量
		if m.vectorDB != nil {
			// 设置活动集合
			m.vectorDB.SetCollection(dir.CollectionName)
			
			// 计算当前集合的点数量
			points, err := m.vectorDB.CountPoints(context.Background(), nil)
			if err != nil {
				// 检查错误是否为集合不存在的错误
				if strings.Contains(err.Error(), "doesn't exist") {
					// 集合不存在，跳过此目录
					logger.Info("Vector database collection does not exist", 
						zap.String("directory", dir.DirectoryPath), 
						zap.String("collection", dir.CollectionName))
					continue
				}
				// 其他错误，记录日志但继续处理其他目录
				logger.Error("Failed to count points in collection", 
					zap.String("directory", dir.DirectoryPath), 
					zap.String("collection", dir.CollectionName), 
					zap.Error(err))
				continue
			}
			
			// 累加点数量
			totalPoints += points
			logger.Info("Collection point count", 
				zap.String("collection", dir.CollectionName),
				zap.Uint64("points", points))
		}
	}
	
	// 如果没有有效的索引时间，使用当前时间
	if lastIndexedTime.IsZero() {
		lastIndexedTime = time.Now()
	}
	
	// 获取当前正在运行的索引任务
	var isIndexing bool
	m.taskMutex.RLock()
	for _, task := range m.indexingTasks {
		if task.Status == "running" {
			isIndexing = true
			break
		}
	}
	m.taskMutex.RUnlock()

	// 构建索引状态
	status := &model.IndexStatus{
		TotalFiles:      totalFiles,
		IndexedFiles:    indexedFiles,
		TotalChunks:     int(totalPoints),
		IndexedChunks:   int(totalPoints),
		LastIndexedTime: lastIndexedTime,
		IsIndexing:      isIndexing,
	}

	logger.Info("Index status calculated", 
		zap.Int("total_files", totalFiles),
		zap.Int("indexed_files", indexedFiles),
		zap.Int("total_chunks", int(totalPoints)),
		zap.Bool("is_indexing", isIndexing))

	return status, nil
}

// GetTask 获取任务信息
func (m *IndexManager) GetTask(taskID string) (*IndexingTask, bool) {
	m.taskMutex.RLock()
	defer m.taskMutex.RUnlock()
	
	task, exists := m.indexingTasks[taskID]
	return task, exists
}

// CancelTask 取消任务
func (m *IndexManager) CancelTask(taskID string) error {
	m.taskMutex.Lock()
	defer m.taskMutex.Unlock()
	
	if task, exists := m.indexingTasks[taskID]; exists {
		if task.Status == "running" {
			task.Status = "cancelled"
			return nil
		}
		return fmt.Errorf("task is not running")
	}
	
	return fmt.Errorf("task not found")
}

// ClearIndexChunks 清除索引分块
func (m *IndexManager) ClearIndexChunks(directory string) error {
	if directory == "" {
		// 清除所有目录的索引
		return m.clearAllIndexChunks()
	}

	// 清除指定目录的索引
	return m.clearDirectoryIndexChunks(directory)
}

// clearAllIndexChunks 清除所有索引分块
func (m *IndexManager) clearAllIndexChunks() error {
	logger.Info("Clearing all index chunks")
	
	// 获取所有目录
	directories, err := m.directoryMgr.ListAllDirectories()
	if err != nil {
		return fmt.Errorf("failed to list directories: %w", err)
	}
	
	// 删除每个目录的向量数据库集合
	if m.vectorDB != nil {
		logger.Info("Deleting vector points from all collections", zap.Int("collections", len(directories)))
		
		for _, dir := range directories {
			logger.Info("Deleting points from collection", 
				zap.String("collection", dir.CollectionName),
				zap.String("directory", dir.DirectoryPath))
			
			// 设置当前集合
			m.vectorDB.SetCollection(dir.CollectionName)
			
			// 删除集合中的所有点
			if err := m.vectorDB.DeleteAllPoints(context.Background()); err != nil {
				logger.Error("Failed to delete points from collection", 
					zap.String("collection", dir.CollectionName), 
					zap.String("directory", dir.DirectoryPath),
					zap.Error(err))
				// 继续处理其他集合，但记录错误
			} else {
				logger.Info("Successfully deleted points from collection", 
					zap.String("collection", dir.CollectionName))
			}
		}
	} else {
		logger.Warn("Vector database is not available, skipping vector deletion")
	}
	
	// 删除SQLite中所有文件记录
	logger.Info("Deleting all file records from SQLite")
	if err := m.fileMonitorRepo.DeleteAllFileRecords(); err != nil {
		logger.Error("Failed to delete all file records from SQLite", zap.Error(err))
		return fmt.Errorf("failed to delete file records: %w", err)
	}
	
	// 删除所有目录记录
	logger.Info("Deleting all directory records")
	for _, dir := range directories {
		if err := m.fileMonitorRepo.DeleteDirectoryRecord(dir.ID); err != nil {
			logger.Error("Failed to delete directory record", 
				zap.String("directory", dir.DirectoryPath), 
				zap.Error(err))
		} else {
			logger.Info("Successfully deleted directory record", 
				zap.String("directory", dir.DirectoryPath))
		}
	}
	
	logger.Info("All index chunks cleared successfully")
	return nil
}

// clearDirectoryIndexChunks 清除指定目录的索引分块
func (m *IndexManager) clearDirectoryIndexChunks(directory string) error {
	logger.Info("Clearing index chunks for directory", zap.String("directory", directory))
	
	// 标准化目录路径
	normalizedDirectory := filepath.Clean(directory)
	
	// 获取目录记录
	dirRecord, err := m.directoryMgr.GetDirectoryRecord(normalizedDirectory)
	if err != nil {
		return fmt.Errorf("failed to get directory record: %w", err)
	}
	
	if dirRecord == nil {
		logger.Warn("Directory not found in records", zap.String("directory", normalizedDirectory))
		return nil
	}
	
	// 删除向量数据库中的点
	if m.vectorDB != nil {
		logger.Info("Deleting vector points for directory", 
			zap.String("directory", normalizedDirectory),
			zap.String("collection", dirRecord.CollectionName))
		
		// 设置活动集合
		m.vectorDB.SetCollection(dirRecord.CollectionName)
		
		// 首先尝试使用过滤器删除指定目录的点
		filter := &vector.Filter{
			Must: []vector.Condition{
				{
					Key:   "directory_path",
					Match: &vector.MatchValue{Value: normalizedDirectory},
				},
			},
		}
		
		if err := m.vectorDB.DeletePointsByFilter(context.Background(), filter); err != nil {
			logger.Warn("Failed to delete points by filter, trying to delete all points", 
				zap.String("collection", dirRecord.CollectionName), 
				zap.Error(err))
			
			// 如果过滤器删除失败，删除集合中的所有点
			if err := m.vectorDB.DeleteAllPoints(context.Background()); err != nil {
				logger.Error("Failed to delete all points from collection", 
					zap.String("collection", dirRecord.CollectionName), 
					zap.Error(err))
				return fmt.Errorf("failed to delete vector points: %w", err)
			}
		}
		
		logger.Info("Vector points deleted successfully", 
			zap.String("directory", normalizedDirectory),
			zap.String("collection", dirRecord.CollectionName))
	} else {
		logger.Warn("Vector database is not available, skipping vector deletion")
	}
	
	// 删除SQLite中指定目录的文件记录
	if err := m.fileMonitorRepo.DeleteFileRecordsByDirectoryID(dirRecord.ID); err != nil {
		logger.Error("Failed to delete file records from SQLite", 
			zap.String("directory", normalizedDirectory), 
			zap.Error(err))
		return fmt.Errorf("failed to delete file records: %w", err)
	}
	
	// 删除目录记录
	if err := m.fileMonitorRepo.DeleteDirectoryRecord(dirRecord.ID); err != nil {
		logger.Error("Failed to delete directory record", 
			zap.String("directory", normalizedDirectory), 
			zap.Error(err))
		return fmt.Errorf("failed to delete directory record: %w", err)
	}
	
	logger.Info("Directory index chunks cleared successfully", zap.String("directory", normalizedDirectory))
	return nil
}